
package com.wyzz.hr.bo.impl;

import java.io.PrintStream;
import java.math.BigDecimal;
import java.util.*;
import org.apache.commons.lang.StringUtils;
import org.hibernate.FetchMode;
import org.hibernate.criterion.*;

import com.wyzz.hr.base.Status;
import com.wyzz.hr.bo.IAttendshiftBO;
import com.wyzz.hr.bo.IEmpshiftBo;
import com.wyzz.hr.bo.ILeavecalendarBO;
import com.wyzz.hr.bo.ILeaverequestBO;
import com.wyzz.hr.bo.ILeavetypeBO;
import com.wyzz.hr.bo.IOvertimetxusedBO;
import com.wyzz.hr.bo.IPositionBo;
import com.wyzz.hr.bo.IStatBO;
import com.wyzz.hr.bo.IWorkFlowBO;
import com.wyzz.hr.dao.ILeaverequestDAO;
import com.wyzz.hr.pojo.Department;
import com.wyzz.hr.pojo.Employee;
import com.wyzz.hr.pojo.Leaverequest;
import com.wyzz.hr.pojo.Leavetype;
import com.wyzz.hr.pojo.Overtimerequest;
import com.wyzz.hr.pojo.Overtimetxused;
import com.wyzz.hr.pojo.Position;
import com.wyzz.hr.spring.SpringBeanFactory;
import com.wyzz.hr.util.BaseCrit;
import com.wyzz.hr.util.DatabaseSysConfigManager;
import com.wyzz.hr.util.DateUtil;
import com.wyzz.hr.util.Pager;
import com.wyzz.hr.vo.ExaminSearchBean;
import com.wyzz.hr.vo.LeaveTotalBean;


public class LeaverequestBOImpl extends EmpApproverBoImpl implements
		ILeaverequestBO {

	public LeaverequestBOImpl() {
	}

	public List getTotalStatusSetList(Employee currentEmp, Date startDate,
			Date endDate, Leavetype lrType, Integer statusSet[]) {
		String fetch[] = {
				Leaverequest.PROP_LR_EMP_NO,
				(new StringBuilder()).append(Leaverequest.PROP_LR_EMP_NO)
						.append(".").append(Employee.PROP_EMP_LOCATION_NO)
						.toString(),
				(new StringBuilder()).append(Leaverequest.PROP_LR_EMP_NO)
						.append(".").append(Employee.PROP_EMP_DEPT_NO)
						.toString(),
				Leaverequest.PROP_LR_CREATE_BY,
				(new StringBuilder()).append(Leaverequest.PROP_LR_CREATE_BY)
						.append(".").append(Employee.PROP_EMP_LOCATION_NO)
						.toString(),
				(new StringBuilder()).append(Leaverequest.PROP_LR_CREATE_BY)
						.append(".").append(Employee.PROP_EMP_DEPT_NO)
						.toString(),
				Leaverequest.PROP_LR_LAST_CHANGE_BY,
				(new StringBuilder()).append(
						Leaverequest.PROP_LR_LAST_CHANGE_BY).append(".")
						.append(Employee.PROP_EMP_LOCATION_NO).toString(),
				(new StringBuilder()).append(
						Leaverequest.PROP_LR_LAST_CHANGE_BY).append(".")
						.append(Employee.PROP_EMP_DEPT_NO).toString(),
				Leaverequest.PROP_LR_EMP_DEPT, Leaverequest.PROP_LR_LT_NO };
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		dc.add(Restrictions.eq(Leaverequest.PROP_LR_EMP_NO, currentEmp));
		dc.add(Restrictions.eq(Leaverequest.PROP_LR_LT_NO, lrType));
		for (int i = 0; i < fetch.length; i++)
			dc.setFetchMode(fetch[i], FetchMode.JOIN);

		dc.add(Restrictions.or(Restrictions.and(Restrictions.ge(
				Leaverequest.PROP_LR_START_DATE, startDate), Restrictions.lt(
				Leaverequest.PROP_LR_START_DATE, endDate)), Restrictions.and(
				Restrictions.le(Leaverequest.PROP_LR_END_DATE, endDate),
				Restrictions.gt(Leaverequest.PROP_LR_END_DATE, startDate))));
		if (statusSet != null) {
			Integer statusSet1[] = new Integer[statusSet.length];
			for (int i = 0; i < statusSet.length; i++)
				statusSet1[i] = statusSet[i];

			dc.add(Restrictions.in(Leaverequest.PROP_LR_STATUS, statusSet1));
		}
		List result = lr_DAO.findByCriteria(dc);
		return result;
	}

	public List delLeaveRequest(String lrID, Employee currentEmp) {
		List result = new ArrayList();
		try {
			lr_DAO.deleteObject(com.wyzz.hr.pojo.Leaverequest.class, lrID);
			sl_BO.deleteLogs("leaverequest", (new StringBuilder()).append("")
					.append(lrID).toString());
		} catch (Exception e) {
			return result;
		}
		return result;
	}

	public void examinSearch(ExaminSearchBean searchBean, DetachedCriteria dc,
			Pager page) {
		String fetch[] = { Leaverequest.PROP_LR_CREATE_BY,
				Leaverequest.PROP_LR_EMP_DEPT,
				Leaverequest.PROP_LR_LAST_CHANGE_BY };
		dc.createAlias(Leaverequest.PROP_LR_EMP_NO, "emp", 1);
		dc.createAlias(Leaverequest.PROP_LR_CREATE_BY, "creator");
		dc.createAlias((new StringBuilder())
				.append(Leaverequest.PROP_LR_EMP_NO).append(".").append(
						Employee.PROP_EMP_DEPT_NO).toString(), "empOrgDept", 1);
		dc.createAlias((new StringBuilder())
				.append(Leaverequest.PROP_LR_EMP_NO).append(".").append(
						Employee.PROP_EMP_PB_NO).toString(), "empPbNo", 1);
		dc.createAlias((new StringBuilder())
				.append(Leaverequest.PROP_LR_EMP_NO).append(".").append(
						Employee.PROP_EMP_LOCATION_NO).toString(), "empOrgLoc",
				1);
		dc.createAlias(Leaverequest.PROP_LR_LT_NO, "lrLtNo", 1);
		for (int i = 0; i < fetch.length; i++)
			dc.setFetchMode(fetch[i], FetchMode.JOIN);

		try {
			if (!StringUtils.isEmpty(searchBean.getNo()))
				BaseCrit.addDC(dc, Leaverequest.PROP_LR_NO, "eq",
						new Integer[] { Integer.valueOf(Integer
								.parseInt(searchBean.getNo())) });
		} catch (Exception ex) {
			System.out.println((new StringBuilder()).append(
					"==========error: cannot calc No").append(
					searchBean.getNo()).toString());
		}
		BaseCrit.addDC(dc, Leaverequest.PROP_LR_REASON, "like",
				new String[] { searchBean.getReason() });
		String alias[] = { Leaverequest.PROP_LR_START_DATE,
				Leaverequest.PROP_LR_END_DATE };
		BaseCrit.addDCTwoDateRange(dc, alias, searchBean.getStartDate(),
				searchBean.getEndDate());
		BaseCrit.addDC(dc, Leaverequest.PROP_LR_LT_NO, Leavetype.PROP_LT_NO,
				new Object[] { new Leavetype(searchBean.getTypeNo()) });
		BaseCrit.addDC(dc, Leaverequest.PROP_LR_STATUS, "eq",
				new Integer[] { searchBean.getStatu() });
		BaseCrit.addEmpDC(dc, "emp", searchBean.getEmp());
		BaseCrit.addDeptDC(dc, (new StringBuilder()).append("emp.").append(
				Employee.PROP_EMP_DEPT_NO).toString(), (new StringBuilder())
				.append("emp.").append(Employee.PROP_EMP_PB_NO).toString(),
				Integer.valueOf(1), new Department(searchBean.getDepNo()));
		List result = null;
		if (page != null) {
			setOrder(dc, page.getOrder());
			page.splitPage(dc);
			result = lr_DAO.findByCriteria(dc, page.getPageSize(), page
					.getCurrentPage());
		} else {
			result = lr_DAO.findByCriteria(dc);
		}
		if (result.size() > 0) {
			String leaveType = DatabaseSysConfigManager.getInstance()
					.getProperty("sys.examin.leave.type");
			for (int i = 0; i < result.size(); i++) {
				Leaverequest lr = (Leaverequest) result.get(i);
				lr.setApplyLRByDay(ExaminDateUtil.applyLRByDay(leaveType, lr
						.getLrLtNo(), lr.getLrEmpNo().getEmpShiftType()));
			}

		}
		searchBean.setResult(result);
	}

	public void approverMgrSearch(ExaminSearchBean searchBean,
			Employee currentEmp, Pager page) {
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		IPositionBo posBo = (IPositionBo) SpringBeanFactory
				.getBean("positionBo");
		Position pos = posBo.getPosByEmpNo(currentEmp.getId(), new String[0]);
		BaseCrit.addDC(dc, Leaverequest.PROP_LR_NEXT_APPROVER, "eq",
				new String[] { pos.getId() });
		BaseCrit.addDC(dc, Leaverequest.PROP_LR_STATUS, "in",
				Status.IN_MGR_PROCESS);
		examinSearch(searchBean, dc, page);
	}

	public void approverHRSearch(ExaminSearchBean searchBean, Pager page) {
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		dc.add(Restrictions.isNull(Leaverequest.PROP_LR_NEXT_APPROVER));
		dc.add(Restrictions.in(Leaverequest.PROP_LR_STATUS, Status.IN_PROCESS));
		examinSearch(searchBean, dc, page);
	}

	public void lrAllSearch(ExaminSearchBean searchBean, Pager page) {
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		examinSearch(searchBean, dc, page);
	}

	public Map getLeaveTotal(String empId) {
		if (empId == null || empId.length() == 0)
			return null;
		Map result = new HashMap();
		Calendar calendar = Calendar.getInstance();
		String hql = (new StringBuilder())
				.append(
						"select lrLtNo.ltName, sum(lrTotalHours), count(*), sum(lrTotalDays) from Leaverequest where (lrStatus in (2,5,14,15,16)) and lrEmpNo.id='")
				.append(empId).append("' and YEAR(lrStartDate)=").append(
						calendar.get(1)).append("group by lrLtNo.ltName ")
				.toString();
		List totalList = lr_DAO.exeHqlList(hql);
		if (totalList == null)
			return null;
		hql = (new StringBuilder())
				.append(
						"select lrLtNo.ltName, sum(lrTotalHours), count(*), sum(lrTotalDays) from Leaverequest where lrStatus in (15,16) and lrEmpNo.id='")
				.append(empId).append("' and YEAR(lrStartDate)=").append(
						calendar.get(1)).append(" group by lrLtNo.ltName")
				.toString();
		List useList = lr_DAO.exeHqlList(hql);
		double total = 0.0D;
		double toApproval = 0.0D;
		int useIndex = 0;
		for (int i = 0; i < totalList.size(); i++) {
			Object items[] = (Object[]) (Object[]) totalList.get(i);
			Object useItems[];
			if (useList == null || useIndex >= useList.size())
				useItems = (new Object[] { "0", "0.0", "0", "0.0" });
			else
				useItems = (Object[]) (Object[]) useList.get(useIndex);
			LeaveTotalBean leaveTotal = new LeaveTotalBean();
			leaveTotal.setType(items[0].toString());
			String totalHours = "0";
			String totalDays = "0";
			String totalTimes = "0";
			double toApproveHours = Double.parseDouble(items[1].toString());
			double toApproveDays = Double.parseDouble(items[3].toString());
			int toApproveTimes = Integer.parseInt(items[2].toString());
			if (items[0].equals(useItems[0])
					|| "0".equals(((Object) (useItems)))) {
				totalHours = useItems[1].toString();
				totalTimes = useItems[2].toString();
				totalDays = useItems[3].toString();
				toApproveHours -= Double.parseDouble(useItems[1].toString());
				toApproveDays -= Double.parseDouble(useItems[3].toString());
				toApproveTimes -= Integer.parseInt(useItems[2].toString());
				useIndex++;
				total += Double.parseDouble(useItems[1].toString());
			}
			toApproval += toApproveHours;
			leaveTotal.setTotalhours(totalHours);
			leaveTotal.setTotaldays(totalDays);
			leaveTotal.setTotalTimes(totalTimes);
			leaveTotal.setToApproveHours((new Double(toApproveHours))
					.toString());
			leaveTotal.setToApproveDays((new Double(toApproveDays)).toString());
			leaveTotal.setToApproveTimes((new Integer(toApproveTimes))
					.toString());
			result.put(items[0].toString(), leaveTotal);
		}

		return result;
	}

	public BigDecimal[] getTotalUsedDay(Employee currentEmp, int year,
			Leavetype lrType, int statusSet[]) {
		Date startDate = DateUtil.getYearFirstDay(year);
		Date endDate = DateUtil.getYearFirstDay(year + 1);
		String hql = "";
		hql = (new StringBuilder())
				.append(
						"select sum(lr.lrTotalHours),sum(lr.lrTotalDays) from Leaverequest lr where lr.lrEmpNo.id='")
				.append(currentEmp.getId())
				.append(
						"' and lr.lrStartDate >=? and lr.lrStartDate <? and lr.lrLtNo = '")
				.append(lrType.getLtNo()).append("'").toString();
		if (statusSet.length > 0) {
			hql = (new StringBuilder()).append(hql).append(" and ( ")
					.toString();
			for (int i = 0; i < statusSet.length; i++) {
				hql = (new StringBuilder()).append(hql).append(
						" (lr.lrStatus = ").append(statusSet[i]).append(" ) ")
						.toString();
				if (i + 1 < statusSet.length)
					hql = (new StringBuilder()).append(hql).append(" or ")
							.toString();
			}

			hql = (new StringBuilder()).append(hql).append(")").toString();
		}
		Object rs = lr_DAO.exeHqlObject(hql,
				new Object[] { startDate, endDate });
		Object result[] = (Object[]) (Object[]) rs;
		BigDecimal rs0 = (BigDecimal) result[0];
		BigDecimal rs1 = (BigDecimal) result[1];
		return (new BigDecimal[] { rs0, rs1 });
	}

	public List loadLeaveRequests(String lrIDs[], String fetch[]) {
		List result;
		try {
			DetachedCriteria dc = DetachedCriteria
					.forClass(com.wyzz.hr.pojo.Leaverequest.class);
			for (int i = 0; i < fetch.length; i++)
				dc.setFetchMode(fetch[i], FetchMode.JOIN);

			BaseCrit.addDC(dc, Leaverequest.PROP_LR_ID, "in", lrIDs);
			dc.addOrder(Order.asc(Leaverequest.PROP_LR_NO));
			result = lr_DAO.findByCriteria(dc);
			if (result.size() == 0)
				return null;
		} catch (Exception e) {
			return null;
		}
		return result;
	}

	public Leaverequest loadLeaverequest(String lrID) {
		String fetch[] = {
				Leaverequest.PROP_LR_EMP_NO,
				(new StringBuilder()).append(Leaverequest.PROP_LR_EMP_NO)
						.append(".").append(Employee.PROP_EMP_LOCATION_NO)
						.toString(),
				(new StringBuilder()).append(Leaverequest.PROP_LR_EMP_NO)
						.append(".").append(Employee.PROP_EMP_DEPT_NO)
						.toString(),
				Leaverequest.PROP_LR_CREATE_BY,
				(new StringBuilder()).append(Leaverequest.PROP_LR_CREATE_BY)
						.append(".").append(Employee.PROP_EMP_LOCATION_NO)
						.toString(),
				(new StringBuilder()).append(Leaverequest.PROP_LR_CREATE_BY)
						.append(".").append(Employee.PROP_EMP_DEPT_NO)
						.toString(),
				Leaverequest.PROP_LR_LAST_CHANGE_BY,
				(new StringBuilder()).append(
						Leaverequest.PROP_LR_LAST_CHANGE_BY).append(".")
						.append(Employee.PROP_EMP_LOCATION_NO).toString(),
				(new StringBuilder()).append(
						Leaverequest.PROP_LR_LAST_CHANGE_BY).append(".")
						.append(Employee.PROP_EMP_DEPT_NO).toString(),
				Leaverequest.PROP_LR_EMP_DEPT, Leaverequest.PROP_LR_LT_NO };
		Leaverequest resultLR = (Leaverequest) lr_DAO.loadObject(
				com.wyzz.hr.pojo.Leaverequest.class, lrID, fetch,
				new boolean[0]);
		return resultLR;
	}

	public Leaverequest loadOneLeaverequest(String lrId, String fetch[]) {
		Object obj = lr_DAO.loadObject(com.wyzz.hr.pojo.Leaverequest.class,
				lrId, fetch, new boolean[0]);
		if (obj != null)
			return (Leaverequest) obj;
		else
			return null;
	}

	private void setOrder(DetachedCriteria detachedCriteria, String order) {
		if (order != null && order.trim().length() > 1
				&& order.indexOf("-") > -1) {
			String ordeName = null;
			String operate = null;
			String params[] = order.split("-");
			if (params.length > 0)
				ordeName = params[0];
			if (params.length > 1)
				operate = params[1];
			if (ordeName.equals("id"))
				if (operate.equals("up"))
					detachedCriteria.addOrder(Order
							.asc(Leaverequest.PROP_LR_NO));
				else
					detachedCriteria.addOrder(Order
							.desc(Leaverequest.PROP_LR_NO));
			if (ordeName.equals("dep"))
				if (operate.equals("up"))
					detachedCriteria.addOrder(Order
							.asc((new StringBuilder()).append("empOrgDept.")
									.append(Department.PROP_DEPARTMENT_NAME)
									.toString()));
				else
					detachedCriteria.addOrder(Order
							.desc((new StringBuilder()).append("empOrgDept.")
									.append(Department.PROP_DEPARTMENT_NAME)
									.toString()));
			if (ordeName.equals("emp"))
				if (operate.equals("up"))
					detachedCriteria.addOrder(Order.asc((new StringBuilder())
							.append("emp.").append(Employee.PROP_EMP_NAME)
							.toString()));
				else
					detachedCriteria.addOrder(Order.desc((new StringBuilder())
							.append("emp.").append(Employee.PROP_EMP_NAME)
							.toString()));
			if (ordeName.equals("type"))
				if (operate.equals("up"))
					detachedCriteria.addOrder(Order.asc((new StringBuilder())
							.append(Leaverequest.PROP_LR_LT_NO).append(".")
							.append(Leavetype.PROP_LT_NAME).toString()));
				else
					detachedCriteria.addOrder(Order.desc((new StringBuilder())
							.append(Leaverequest.PROP_LR_LT_NO).append(".")
							.append(Leavetype.PROP_LT_NAME).toString()));
			if (ordeName.equals("reason"))
				if (operate.equals("up"))
					detachedCriteria.addOrder(Order
							.asc(Leaverequest.PROP_LR_REASON));
				else
					detachedCriteria.addOrder(Order
							.desc(Leaverequest.PROP_LR_REASON));
			if (ordeName.equals("startT"))
				if (operate.equals("up"))
					detachedCriteria.addOrder(Order
							.asc(Leaverequest.PROP_LR_START_DATE));
				else
					detachedCriteria.addOrder(Order
							.desc(Leaverequest.PROP_LR_START_DATE));
			if (ordeName.equals("endT"))
				if (operate.equals("up"))
					detachedCriteria.addOrder(Order
							.asc(Leaverequest.PROP_LR_END_DATE));
				else
					detachedCriteria.addOrder(Order
							.desc(Leaverequest.PROP_LR_END_DATE));
			if (ordeName.equals("total"))
				if (operate.equals("up"))
					detachedCriteria.addOrder(Order
							.asc(Leaverequest.PROP_LR_TOTAL_HOURS));
				else
					detachedCriteria.addOrder(Order
							.desc(Leaverequest.PROP_LR_TOTAL_HOURS));
			if (ordeName.equals("statu"))
				if (operate.equals("up"))
					detachedCriteria.addOrder(Order
							.asc(Leaverequest.PROP_LR_STATUS));
				else
					detachedCriteria.addOrder(Order
							.desc(Leaverequest.PROP_LR_STATUS));
		} else {
			detachedCriteria.addOrder(Order.desc(Leaverequest.PROP_LR_NO));
		}
	}

	public void deleteLeaverequest(String lrIds[]) {
		IOvertimetxusedBO otuBO = (IOvertimetxusedBO) SpringBeanFactory
				.getBean("overtimetxusedBO");
		Map otuMap = otuBO.searchOvertimetxusedByLrIds(lrIds);
		if (!otuMap.isEmpty()) {
			List deleteList = new ArrayList();
			List updateList = new ArrayList();
			String arr$[] = lrIds;
			int len$ = arr$.length;
			for (int i$ = 0; i$ < len$; i$++) {
				String lrId = arr$[i$];
				if (!otuMap.containsKey(lrId))
					continue;
				List otuList = (List) otuMap.get(lrId);
				List orList = new ArrayList();
				Overtimerequest or;
				for (Iterator it = otuList.iterator(); it.hasNext(); orList
						.add(or)) {
					Overtimetxused otu = (Overtimetxused) it.next();
					or = otu.getOtuOrId();
					or.setOrTiaoxiuHoursRemain(new BigDecimal(or
							.getOrTiaoxiuHoursRemain().doubleValue()
							+ otu.getOtuHours().doubleValue()));
				}

				deleteList.addAll(otuList);
				updateList.addAll(orList);
			}

			lr_DAO.deleteCollection(deleteList);
			lr_DAO.saveOrupdate(updateList);
		}
		String arr$[] = lrIds;
		int len$ = arr$.length;
		for (int i$ = 0; i$ < len$; i$++) {
			String lrId = arr$[i$];
			lr_DAO.deleteObject(com.wyzz.hr.pojo.Leaverequest.class, lrId);
		}

	}

	public ILeavetypeBO getLt_BO() {
		return lt_BO;
	}

	public void setLt_BO(ILeavetypeBO lt_BO) {
		this.lt_BO = lt_BO;
	}

	public IStatBO getSt_BO() {
		return st_BO;
	}

	public void setSt_BO(IStatBO st_BO) {
		this.st_BO = st_BO;
	}

	public ILeavecalendarBO getLc_BO() {
		return lc_BO;
	}

	public void setLc_BO(ILeavecalendarBO lc_BO) {
		this.lc_BO = lc_BO;
	}

	public IAttendshiftBO getAttendBo() {
		return attendBo;
	}

	public void setAttendBo(IAttendshiftBO attendBo) {
		this.attendBo = attendBo;
	}

	public LrDataCheckImpl getLrDataCheckBO() {
		return lrDataCheckBO;
	}

	public void setLrDataCheckBO(LrDataCheckImpl lrDataCheckBO) {
		this.lrDataCheckBO = lrDataCheckBO;
	}

	public IEmpshiftBo getEmpShiftBo() {
		return empShiftBo;
	}

	public void setEmpShiftBo(IEmpshiftBo empShiftBo) {
		this.empShiftBo = empShiftBo;
	}

	public IWorkFlowBO getWorkFlowBo() {
		return workFlowBo;
	}

	public void setWorkFlowBo(IWorkFlowBO workFlowBo) {
		this.workFlowBo = workFlowBo;
	}

	public ILeaverequestDAO getLr_DAO() {
		return lr_DAO;
	}

	public void setLr_DAO(ILeaverequestDAO lr_DAO) {
		this.lr_DAO = lr_DAO;
	}

	private ILeaverequestDAO lr_DAO;
	private IEmpshiftBo empShiftBo;
	private IAttendshiftBO attendBo;
	public static final String table_name = "leaverequest";
	private ILeavetypeBO lt_BO;
	private IWorkFlowBO workFlowBo;
	private IStatBO st_BO;
	private ILeavecalendarBO lc_BO;
	private LrDataCheckImpl lrDataCheckBO;
}
